#include "led.h"

static volatile uint16_t data reloaddata;
static volatile uint16_t data cyclecount;

/*cyclecount计数序列:
0x0202(258)
0x0201(257)
0x0100(256)
0x01FF(255)
...
0x0101(1)
0x0000(done)

所以：
high = (d + 255) >> 8
low  = (d)
*/

void T1_ISR(void) interrupt 3 using 1 {
#pragma ASM
	CLR     EA
	CLR		TR1 ;停止计时器，防止高低位读取时错误
	MOV     A, reloaddata ;LOW
	ADD     A, TL1
	MOV     TL1, A ;TL加上重载值低位
	MOV     A, (reloaddata+1) ;HIGH
	ADDC    A, TH1
	MOV     TH1, A ;TH加上重载值高位
	SETB    TR1 ;恢复计时器
	SETB    EA ;恢复中断
	XRL     SPK_PORT, #SPK_BITMASK ;蜂鸣器反转
	CLR     C
	DJNZ    cyclecount, NZ1 ;LOW
	DJNZ    (cyclecount+1), NZ1 ;HIGH
	;计数结束
	ANL     SPK_PORT, #SPK_BITMASK_NEG ;STOP SPEAKER
	ORL     LED_PORT, #LED_BITMASK ;DIM LED
	CLR     TR0 ;STOP TIMER
NZ1:RETI
#pragma ENDASM
}

void LEDSPK_Init(void) {
	LED_PORT |= LED_BITMASK;
	SPK_PORT &= ~SPK_BITMASK;
	TR1 = 0;//stop timer
	ET1 = 1;//enable interrupt
	EA = 1;//enable global interrupt
}

void LEDSPK_Flash(uint8_t ledmask_neg, uint16_t reload, uint16_t cycle) {
	TH1 = (uint8_t)(reload >> 8);
	TL1 = (uint8_t)reload;
	LED_PORT &= ledmask_neg;
	cyclecount = cycle;
	reloaddata = reload;
	TMOD &= 0x0F;
	TMOD |= 0x10;//T1 = 16 bit mode
	TR1 = 1;//run
}